<template>
  <div class="app-container">
    <div class="filter-container" id="filter-container-TmptAuthUserA2roleList">
      <span v-for="(c,i) in showConditions" :key="i" style="margin-right: 5px;">
        <el-input
            v-if="c.type=='input'"
            v-model="listQuery[c.property]"
            size="small"
            :placeholder="c.label"
            style="width: 200px; "
            class="filter-item"
            @keyup.enter.native="handleFilter"
            clearable
        />

        <select-option
            v-else-if="c.type=='select'"
            v-model="listQuery[c.property]"
            size="small"
            class="filter-item"
            :placeholder="c.label"
            :clearable=true
            :prop-name=c.enumName
            :prop-ds-type=c.dataResource
            :prop-url="c.remoteUrl"
        />

        <el-date-picker
            v-else-if="c.type=='date-range'"
            v-model="listQuery[c.property]"
            type="daterange"
            value-format="yyyy-MM-dd"
            align="left"
            unlink-panels
            range-separator="至"
            :start-placeholder="c.label+':  开始'"
            end-placeholder="结束"
            :picker-options="pickerOptions"
            size="small"
            class="filter-item"
            @keyup.enter.native="handleFilter"
        />
        <el-date-picker
            v-else-if="c.type=='date'"
            v-model="listQuery[c.property]"
            type="date"
            value-format="yyyy-MM-dd"
            align="left"
            unlink-panels
            :placeholder="c.label"
            :picker-options="pickerOptions"
            size="small"
            class="filter-item"
            @keyup.enter.native="handleFilter"
        />
      </span>
      <el-button :loading="queryLoading" class="filter-item" size="small" type="primary" plain icon="el-icon-search" @click="handleFilter">
        查询
      </el-button>
      <el-button :loading="downloadLoading" class="filter-item" size="small" type="primary" plain icon="el-icon-download" @click="handleDownload">
        导出报表
      </el-button>
      <el-button v-show="hasPermission(['tmptAuthUserA2roleList:create'])" class="filter-item" size="small" type="primary" plain icon="el-icon-plus" @click="handleCreate">
        添加
      </el-button>
      <el-button class="filter-item" size="small" icon="el-icon-setting" @click="pageSettingVisible=true">
        页面设置
      </el-button>
    </div>

    <el-table
      :key="tableKey"
      v-loading="listLoading"
      :data="list"
      border
      fit
      highlight-current-row
      :show-summary="false"
      :summary-method="getSummaries"
      :height="tableHeight"
      @sort-change="sortChange"
      @header-dragend="headerDragend"
      @row-click="handleRowClick"
      style="width: 100%;"
    >
        <!-- 行展开，显示的详细信息 -->
        <el-table-column v-if="isExpandedRow" type="expand">
        <template slot-scope="props">
          <el-form label-position="left" inline class="demo-table-expand">
            <el-form-item
                v-for="(col, index) in showTheads4Details"
                :key="index"
                :label="col.label"
                label-width="200px">
                <span v-if="col.property.indexOf('.') === -1">{{ props.row[col.property] }}</span>
                <span v-else>{{ props.row[col.property.split('.')[0]]|getJsonName([col.property.split('.')[1]]) }}</span> <!-- 当属性是一个json对象时 -->
            </el-form-item>
          </el-form>

        </template>
        </el-table-column>

        <el-table-column
            v-for="(col, index) in showTheads"
            :key="index"
            :label="col.label"
            :prop="col.property"
            :sortable="col.sort"
            :sort-orders="['ascending', 'descending']"
            :min-width="col.width"
            :fixed="col.fixed"
        >
          <template slot-scope="{row}">
              <span v-if="col.property.indexOf('.') === -1">{{ row[col.property] }}</span>
              <span v-else>{{ row[col.property.split('.')[0]]|getJsonName([col.property.split('.')[1]]) }}</span> <!-- 当属性是一个json对象时, 多对一关联时，一的一方，只做展示用 -->
          </template>
        </el-table-column>

        <!--操作Button + 页面级权限控制:hasPermission -->
        <span v-if="hasPermission(['tmptAuthUserA2roleList:update','tmptAuthUserA2roleList:delete'])">
            <el-table-column v-if="!isDropMenu" fixed="right" label="操作" align="center" min-width="280">
                <template slot="header">
                  <el-checkbox v-model="isDropMenu" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1">
                      平铺 > 下拉
                  </el-checkbox>
                </template>
                <template slot-scope="{row}">
                  <el-button v-show="hasPermission(['tmptAuthUserA2roleList:update'])" type="primary" icon="el-icon-edit" title="编辑" size="mini" @click="handleUpdate(row)"></el-button>
                  <el-button v-show="hasPermission(['tmptAuthUserA2roleList:delete'])" type="danger" icon="el-icon-delete" title="删除" size="mini" @click="handleDelete(row)"></el-button>
                </template>
            </el-table-column>
            <!--下拉-->
            <el-table-column v-else fixed="right" label="操作" align="center" min-width="140">
              <template slot="header">
                <el-checkbox v-model="isDropMenu" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1">
                  下拉 > 平铺
                </el-checkbox>
              </template>
              <template slot-scope="{row, $index}">
                  <el-dropdown @command="handleCommand">
                      <el-button type="primary" size="mini">
                          菜单<i class="el-icon-arrow-down el-icon--right" />
                      </el-button>
                      <el-dropdown-menu slot="dropdown">
                          <el-dropdown-item v-show="hasPermission(['tmptAuthUserA2roleList:update'])" :command="beforeHandleCommand(row, 'update', $index)">编辑</el-dropdown-item>
                          <el-dropdown-item v-show="hasPermission(['tmptAuthUserA2roleList:delete'])" :command="beforeHandleCommand(row, 'delete', $index)">删除</el-dropdown-item>
                      </el-dropdown-menu>
                  </el-dropdown>
              </template>
            </el-table-column>
        </span>

    </el-table>

    <!-- 分页 -->
    <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />

    <!-- 添加弹出框 -->
    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" :close-on-click-modal="false">
      <form-details ref="formDetails" :row="row" :isModule="true" @createResult="createResult" @updateResult="updateResult"/>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">
          取消
        </el-button>
        <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
          保存
        </el-button>
      </div>
    </el-dialog>

    <!-- 页面设置 -->
    <el-drawer
            :title="'页面布局参数设置---页面版本号:'+this.pageVersion"
            :visible.sync="pageSettingVisible"
            custom-class="demo-drawer"
            ref="drawer"
            direction="rtl"
            :before-close="handleDrawerClose">
      <el-scrollbar height="100%">
        <div class="demo-drawer__content" style="padding-left: 20px;">
          <el-form>
            <el-form-item>
              <label>查询条件：</label>
              <el-checkbox-group v-model="conditionCheckboxVal" style="margin-left: 20px;">
                <el-checkbox v-for="(c,i) in conditionOptions" :key="i" :label="c.property" style="width: 120px;">{{ c.label }}</el-checkbox>
              </el-checkbox-group>
            </el-form-item>
            <el-form-item>
              <label>是否展开行：</label>
              <el-checkbox v-model="isExpandedRow" style="width: 150px;">展开行显示详情</el-checkbox>
            </el-form-item>
            <el-form-item>
              <label>列表显示列：</label>
              <el-checkbox-group v-model="checkboxVal" style="margin-left: 20px;">
                <el-checkbox v-for="(thead,index) in showTheads4Setting" :key="index" :label="thead.property" style="width: 120px;">{{ thead.label }}</el-checkbox>
              </el-checkbox-group>
            </el-form-item>
            <el-form-item>
              <label>表列宽度调整：</label>
              <span>鼠标放置在列与列中间，出现左右调整符，可左右拖动调整。</span>
            </el-form-item>
          </el-form>
        </div>
      </el-scrollbar>
      <div class="demo-drawer__footer">
        <el-button style="width: 80%;" @click="savePageSetting">关    闭</el-button>
      </div>
    </el-drawer>

  </div>
</template>

<script>
import {fetchList, deleteApi} from './api'
import waves from '@/directive/waves' // waves directive
import { parseTime, reorgQueryParams, resizeTableHeight } from '@/utils'
import checkPermission from '@/utils/permission'
import storageUtil from '@/utils/StorageUtil'
import Pagination from '@/components/Pagination' // secondary package based on el-pagination
import FormDetails from './form-details.vue' // add form form dialog
// 从当前View的私有数据对象中取数据
import { PageVersionKey, ConditionShowListCkedKey, ColumnShowListCkedKey, isDropMenuKey, ColumnShowListWidthKey, IsExpandedRowCkedKey, conditionOptions, theadOptions, pickerOptions, pickerOptionsSingleDate } from './data'
// 导入多选项组件
import SelectOption from '@/views/coding/components/SelectOption'

export default {
    name: 'TmptAuthUserA2roleList-ComplexList',
    components: { Pagination, FormDetails, SelectOption },
    directives: { waves },

    props: {
        // 当作为侧边日历查询的子组件时，接收父组件的传值，watch中查询
        paramDateArr: Array,
        // 作为子组件时，需要回调传值；应用场景：一对多关联查询时，点击左边查询列表，传值给右边子列表，查询子列表结果
        isModule: {
            type: Boolean,
            default: false
        },
        // 当作为侧边查询结果显示的右子组件时，接收父组件的传值，watch中查询
        parentRow: Object
    },

    filters: {
        statusFilter(status) {
            const statusMap = {
                published: 'success',
                draft: 'info',
                deleted: 'danger'
            }
            return statusMap[status]
        }
    },

    data() {
        return {
            pageVersion: '1',
            tableKey: 0,
            // 控制行尾菜单显示模式（下拉->平铺）
            isDropMenu: storageUtil.readBool(isDropMenuKey),
            // 默认表头控制
            theadOptions: theadOptions,
            checkboxVal: [], // checkboxVal
            showTheads: [], // 默认表头 Default header
            showTheads4Setting: [], // 默认表头 Default header, for page setting
            showTheads4Details: [], // 详细信息
            // 查询条件
            conditionOptions: conditionOptions,
            conditionCheckboxVal: [], // 当前checkbox选中的值
            showConditions: [], // 当前显示的condition
            // 列表
            list: [],
            total: 0,
            footer: [],
            listLoading: false,
            queryLoading: false,
            downloadLoading: false,
            listQuery: {
                page: 1,
                limit: 20,
                createdate: [] // 不加此项，watch里监控侧边日历父组件，传的日期参数，有问题； 子页面时间查询框清不掉查询参数。
            },
            importanceOptions: [1, 2, 3],
            sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
            statusOptions: ['published', 'draft', 'deleted'],
            dialogFormVisible: false,
            dialogStatus: '',
            textMap: {
                update: '编辑',
                create: '新增'
            },
            downloadLoading: false,
            pickerOptions: pickerOptions,
            pickerOptionsSingleDate: pickerOptionsSingleDate,
            row: {},
            pageSettingVisible: false, // 页面布局设置
            isExpandedRow: storageUtil.readBool(IsExpandedRowCkedKey), // 是否展开行
            tableHeight:0, // 表格高度
            filterContainerHeight: 0, // 查询容器高度
            clientHeight: 0 // 浏览器高度
        }
    },

    watch: {
        conditionCheckboxVal(valArr) {
            this.showConditions = this.conditionOptions.filter(i => valArr.indexOf(i.property) >= 0)
        },
        checkboxVal(valArr) {
            this.showTheads = this.theadOptions.filter(i => valArr.indexOf(i.property) >= 0 && i.show)
            this.tableKey = this.tableKey + 1// 为了保证table 每次都会重渲 In order to ensure the table will be re-rendered each time
        },
        isDropMenu(val) {
            storageUtil.save(isDropMenuKey, val, true)
        },
        // 当作为侧边日历查询的子组件时，接收父组件的传值，watch中查询
        paramDateArr(val) {
            this.listQuery.createdate = val // 默认用createdate作查询参数
            this.handleFilter()
        },
        // 当作为侧边查询的子组件时，接收父组件的传值，watch中查询
        parentRow(pRow) {
            this.listQuery[pRow.parentPropName] = pRow.id // parantId, 需修改成主表ID。******
            this.handleFilter()
        }
    },

    created() {
        // 页面布局
        this.initLayout()
        // OneToMany查询时，接收外键ID
        const parentId = this.$route.params.parentId
        const parentPropName = this.$route.params.parentPropName
        if (parentId!==undefined && parentPropName!==undefined) {
            this.listQuery[parentPropName] = parentId
        }
        // 查询
        this.getList()
    },

    mounted () {
        // 浏览器、元素大小变化时，动态调整table高度
        resizeTableHeight(this, 'filter-container-TmptAuthUserA2roleList')
    },

    methods: {
        // 页面级权限控制，调用方法如：hasPermission(['a2user:delete'])
        hasPermission(needPermisions) {
            return checkPermission(needPermisions)
        },
        // 初始化布局：查询条件、显示列表元素及宽度等
        initLayout() {
            // 显示列处理
            const defaultCheckedThead = []
            theadOptions.forEach(col => {
                if (col.show) {
                    defaultCheckedThead.push(col.property)
                    this.showTheads.push(col)
                    this.showTheads4Setting.push(col)
                }
                this.showTheads4Details.push(col)
            })
            // 看页面版本号，与本地存储的是否一样，不一样话，说明页面升级了，重置参数
            const pageVersionKey = storageUtil.readStr(PageVersionKey)
            if (pageVersionKey === '') {
                // 存储里没有页面版本号，说明第一次使用页面，保存一下
                storageUtil.save(PageVersionKey, this.pageVersion, true)
            }
            else if (pageVersionKey !== this.pageVersion) { // 页面升级过了
                storageUtil.save(ColumnShowListCkedKey, [], true)
                storageUtil.save(ConditionShowListCkedKey, [], true)
                storageUtil.save(PageVersionKey, this.pageVersion, true)
            }
            // read localstorage first，显示哪些列
            const columnShowListCked = storageUtil.readArr(ColumnShowListCkedKey)
            if (columnShowListCked.length === 0) {
                this.checkboxVal = defaultCheckedThead
            } else {
                this.checkboxVal = columnShowListCked
            }
            // 查询条件处理，显示哪些查询条件
            const defaultCheckedCondition = []
            conditionOptions.forEach(col => {
                if (col.show) {
                  defaultCheckedCondition.push(col.property)
                }
            })
            // read localstorage first
            const showConditionsCked = storageUtil.readArr(ConditionShowListCkedKey)
            if (showConditionsCked.length === 0) {
                this.conditionCheckboxVal = defaultCheckedCondition
            } else {
                this.conditionCheckboxVal = showConditionsCked
            }
        },
        // 刷新
        getList() {
            this.queryLoading = true
            this.listLoading = true
            // 重组查询条件
            const params = Object.assign({}, this.listQuery)
            reorgQueryParams(params)
            // 查询
            fetchList(params).then(result => {
                if (!result.success) {
                    this.notify(result)
                    this.queryLoading = false
                    this.listLoading = false
                    return
                }
                this.list = result.map.rows
                this.total = result.map.total
                // footer
                if (result.map.footer && result.map.footer.length>0) {
                    this.footer = result.map.footer
                }
                this.queryLoading = false
                this.listLoading = false
                ++this.tableKey
            })
        },
        // 从第一页开始查询
        handleFilter() {
            this.listQuery.page = 1
            this.getList()
        },
        // 排序
        sortChange(data) {
            const { prop, order } = data
            if (prop === 'id') {
                this.sortByID(order)
            }
        },
        sortByID(order) {
            if (order === 'ascending') {
                this.listQuery.sort = '+id'
            } else {
                this.listQuery.sort = '-id'
            }
            this.handleFilter()
        },
        // SUM
        getSummaries(param) {
            if (this.footer.length == 0) {
                return []
            }
            const sums = [];
            const { columns, data } = param;
            columns.forEach((column, index) => {
                if (index === 0) {
                    sums[index] = '合计';
                    return;
                }
                if (this.footer[0][column.property]) {
                    sums[index] = this.footer[0][column.property]
                    return;
                }
            });
            return sums;
        },
        // download excel
        handleDownload() {
            // 重组查询条件
            const params = Object.assign({}, this.listQuery)
            params.page = 1
            params.limit = 10000000
            reorgQueryParams(params)
            console.log(params)
            // 查询
            this.downloadLoading = true
            fetchList(params).then(result => {
                if (!result.success) {
                    this.notify(result)
                    this.downloadLoading = false
                    return
                }
                import('@/vendor/Export2Excel').then(excel => {
                    const tHeader = ['Id', '名称', '创建时间', '创建人']  // excel中显示的列名
                    const filterVal = ['id', 'name', 'createdate', 'createman'] // excel中显示哪些列，与tHeader对应
                    const list = result.map.rows
                    const data = this.formatJson(filterVal, list)
                    excel.export_json_to_excel({
                        header: tHeader,
                        data,
                        filename: 'excel',
                        autoWidth: true,
                        bookType: 'xlsx'
                    })
                    this.downloadLoading = false
                })
            })
        },
        formatJson(filterVal, jsonData) {
            return jsonData.map(v => filterVal.map(j => {
                if (j === 'timestamp') {
                    return parseTime(v[j])
                } else {
                    return v[j]
                }
            }))
        },
        // 添加操作 start
        handleCreate() {
            this.dialogStatus = 'create'
            this.dialogFormVisible = true
            // 消除上次出现的验证信息
            this.$nextTick(() => {
                this.$refs['formDetails'].clearValidate()
                this.$refs['formDetails'].resetTemp()
                this.$refs['formDetails'].defaultTemp()
            })
        },
        // 调用子组件操作数据
        createData() {
            this.$refs['formDetails'].createData()
        },
        // 子组件操作成功，回调此方法，关闭弹框、刷新
        createResult() {
            this.dialogFormVisible = false
            this.handleFilter()
        },
        // 编辑操作 start
        handleUpdate(row) {
            this.row = Object.assign({}, row) // copy obj
            this.row.deleteflag = this.row.deleteflag.id // 枚举对象，取id值
            this.dialogStatus = 'update'
            this.dialogFormVisible = true
            // 消除上次出现的验证信息
            this.$nextTick(() => {
                this.$refs['formDetails'].clearValidate()
            })
        },
        // 调用子组件操作数据
        updateData() {
            this.$refs['formDetails'].updateData()
        },
        // 子组件操作成功，回调此方法，关闭弹框、刷新
        updateResult() {
            this.dialogFormVisible = false
            this.getList()
        },
        // 下拉操作菜单
        beforeHandleCommand(row, command, index) {
            return {
                'index': index,
                'row': row,
                'command': command
            }
        },
        handleCommand(command) {
            const row = command.row
            switch (command.command) {
                case 'update': {
                    this.handleUpdate(row)
                    break
                }
                case 'delete': {
                      this.handleDelete(row)
                      break
                }
            }
        },
        // 下拉操作菜单 End
        // 删除操作
        handleDelete(row) {
            this.$confirm('确认删除吗？')
            .then(_ => {
                // delete api
                deleteApi({id: '' + row.id}).then((r) => {
                    this.notify(r)
                    if (r.success) {
                        this.getList()
                    }
                })
                // end
            })
            .catch(_ => {})
        },
        // 列宽监听，本地存储
        // 存储格式: {name: 93, url: 115, deleteflag: 140, id: 121}
        headerDragend(newWidth, oldWidth, column, event) {
            const columnWidthJson = storageUtil.readObj(ColumnShowListWidthKey)
            columnWidthJson[column.property] = newWidth
            storageUtil.save(ColumnShowListWidthKey, columnWidthJson, true)
            // 实时修改全局theadOptions中的width, 不然要刷新页面才从localstorage中读取width
            theadOptions.filter(c => c.property === column.property)[0].width = newWidth
        },
        // 关闭Drawer, 自动上传数据保存
        handleDrawerClose() {
            this.savePageSetting()
        },
        // 保存页面设置参数
        savePageSetting() {
            // 查询条件A
            storageUtil.save(ConditionShowListCkedKey, this.conditionCheckboxVal, true)
            // 列
            storageUtil.save(ColumnShowListCkedKey, this.checkboxVal, true)
            // 是否展开行
            storageUtil.save(IsExpandedRowCkedKey, this.isExpandedRow, true)
            // close dialog
            this.pageSettingVisible = false
        },
        // 行点击事件；应用场景：一对多关联查询时，点击左边查询列表，传值给右边子列表，查询子列表结果 xxxxxx
        handleRowClick(row, column, event) {
            // 从父组件调用此方法，进行回调下
            if (this.isModule) {
                row.parentPropName = 'tmptAuthUserA2roleListId'
                this.$emit('input', row)
            }
        },
        // 主页面上调用子列表

    }
}
</script>
<style>
  .demo-table-expand {
    font-size: 0;
  }
  .demo-table-expand label {
    width: 100px;
    color: #99a9bf;
  }
  .demo-table-expand .el-form-item {
    margin-right: 0;
    margin-bottom: 0;
    width: 40%;
  }
  .el-table__body tr.current-row > td {
    background-color: #F0F7FF !important;
  }
  /*表格 element-ui的table改变偶数行背景色*/
  .el-table--striped .el-table__body tr.el-table__row--striped td{
    background: #F5F7FA;
  }
  /*表格 解决element-ui的table表格控件表头与内容列不对齐问题*/
  .el-table th.gutter {
    display: table-cell!important;
  }
  /*抽屉 element-ui的drawer固定底部按钮*/
  .el-drawer__body{
    overflow-y: scroll;
    margin-bottom: 50px;
  }
  .demo-drawer__footer{
    width:100%;
    position:absolute;
    bottom:10px;
    left:10px;
    border-top: 1px solid #eee;
    padding-top: 5px;
    text-align:center;
    background-color:white;
  }
  /*抽屉 去掉element-ui的drawer标题选中状态*/
  :focus{
    outline:0;
  }

  .el-scrollbar__wrap {
    overflow-x: hidden;
  }
</style>
